package com.java.lang;

import java.util.concurrent.TimeUnit;

/**
 * 安全终止线程 <br>
 * 从上面代码可以看出，通过 while (on && !Thread.currentThread().isInterrupted())
 * 代码来实现线程是否跳出执行逻辑，并终止。但是疑问点就来了，为啥需要 on 和 isInterrupted() 两项一起呢？用其中一个方式不就行了吗？答案在下面
 * 
 * 线程成员变量 on 通过 volatile 关键字修饰，达到线程之间可见，从而实现线程的终止。但当线程状态为被阻塞状态（sleep、wait、join
 * 等状态）时，对成员变量操作也阻塞，进而无法执行安全终止线程 为了处理上面的问题，引入了 isInterrupted(); 只去解决阻塞状态下的线程安全终止。
 * 两者结合是真的没问题了吗？不是的，如果是网络 io 阻塞，比如一个 websocket 一直再等待响应，那么直接使用底层的 close 。
 *
 * @author Jeff Lee @ bysocket.com
 * @since 2018年02月23日19:03:02
 */
public class ThreadSafeStop {

    public static void main(String[] args) throws Exception {
        Runner one = new Runner();
        Thread countThread = new Thread(one, "CountThread");
        countThread.start();
        // 睡眠 1 秒，通知 CountThread 中断，并终止线程
        TimeUnit.SECONDS.sleep(1);
        countThread.interrupt();

        Runner two = new Runner();
        countThread = new Thread(two, "CountThread");
        countThread.start();
        // 睡眠 1 秒，然后设置线程停止状态，并终止线程
        TimeUnit.SECONDS.sleep(1);
        two.stopSafely();
    }

    private static class Runner implements Runnable {

        private long i;

        // 终止状态
        private volatile boolean on = true;

        @Override
        public void run() {
            while (on && !Thread.currentThread().isInterrupted()) {
                // 线程执行具体逻辑
                i++;
            }
            System.out.println("Count i = " + i);
        }

        public void stopSafely() {
            on = false;
        }
    }
}
